#include "ModbusService.h"
#include <QDebug>
#include <QMetaType>

ModbusService::ModbusService(QObject *parent)
    : QObject(parent),
      m_modbusClient(nullptr),
      m_connectionState(Disconnected),
      m_currentPort(502),
      m_currentSlaveId(1)
{
    qRegisterMetaType<QModbusDevice::State>("QModbusDevice::State");

    // 创建 Modbus TCP 客户端
    m_modbusClient = new QModbusTcpClient(this);

    // 连接信号
    connect(m_modbusClient, &QModbusClient::stateChanged,
            this, &ModbusService::onStateChanged);
    connect(m_modbusClient, &QModbusClient::errorOccurred,
            this, &ModbusService::onErrorOccurred);

    qDebug() << "ModbusService 初始化完成";
}

ModbusService::~ModbusService()
{
    disconnectFromDevice();
}

// 连接到 Modbus 设备（使用 Device 对象）
bool ModbusService::connectToDevice(const Device &device)
{
    m_currentDeviceId = device.deviceId();
    return connectToDevice(device.ipAddress(), device.port(), device.slaveId());
}

// 连接到 Modbus 设备
bool ModbusService::connectToDevice(const QString &ipAddress, int port, int slaveId)
{
    // 如果已连接，先断开
    if (m_connectionState == Connected || m_connectionState == Connecting)
    {
        qWarning() << "已存在连接，先断开旧连接";
        disconnectFromDevice();
    }

    // 保存设备信息
    m_currentIpAddress = ipAddress;
    m_currentPort = port;
    m_currentSlaveId = slaveId;

    // 设置连接参数
    m_modbusClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, ipAddress);
    m_modbusClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, port);
    m_modbusClient->setTimeout(3000);      // 超时 3 秒
    m_modbusClient->setNumberOfRetries(3); // 重试 3 次

    qInfo() << "正在连接 Modbus 设备:" << ipAddress << ":" << port << "从站ID:" << slaveId;

    // 设置连接中状态
    setConnectionState(Connecting);

    // 发起连接
    if (!m_modbusClient->connectDevice())
    {
        QString error = QString("连接失败: %1").arg(m_modbusClient->errorString());
        setError(error);
        setConnectionState(Error);
        return false;
    }

    return true;
}

// 断开连接
void ModbusService::disconnectFromDevice()
{
    if (m_modbusClient && m_modbusClient->state() != QModbusDevice::UnconnectedState)
    {
        qInfo() << "断开 Modbus 连接:" << m_currentIpAddress;
        m_modbusClient->disconnectDevice();
    }

    setConnectionState(Disconnected);
    m_currentIpAddress.clear();
}

// 读取输入寄存器（功能码 0x04）
bool ModbusService::readInputRegisters(int startAddress, int count)
{
    if (!isConnected())
    {
        setError("设备未连接");
        return false;
    }

    if (count <= 0 || count > 125)
    {
        setError(QString("寄存器数量无效: %1（范围 1-125）").arg(count));
        return false;
    }

    // 创建读取请求（输入寄存器，功能码 0x04）
    QModbusDataUnit readUnit(QModbusDataUnit::InputRegisters, startAddress, count);

    // 发送读取请求
    QModbusReply *reply = m_modbusClient->sendReadRequest(readUnit, m_currentSlaveId);
    if (!reply)
    {
        setError(QString("发送读取请求失败: %1").arg(m_modbusClient->errorString()));
        return false;
    }

    // 检查请求是否立即完成
    if (reply->isFinished())
    {
        delete reply;
        setError("请求立即完成，可能是错误");
        return false;
    }

    // 连接完成信号
    connect(reply, &QModbusReply::finished, this, &ModbusService::onReadReady);

    qDebug() << "发送读取请求: 地址" << startAddress << "数量" << count;
    return true;
}

// 处理连接状态变化
void ModbusService::onStateChanged(QModbusDevice::State state)
{
    switch (state)
    {
    case QModbusDevice::UnconnectedState:
    {
        qInfo() << "Modbus 状态: 未连接";
        QString lastDeviceId = m_currentDeviceId;
        setConnectionState(Disconnected);
        emit disconnected();
        if (!lastDeviceId.isEmpty())
        {
            // 清除记录，以便下次连接重新设置
            m_currentDeviceId.clear();
        }
        break;
    }

    case QModbusDevice::ConnectingState:
        qInfo() << "Modbus 状态: 连接中...";
        setConnectionState(Connecting);
        break;

    case QModbusDevice::ConnectedState:
        qInfo() << "Modbus 状态: 已连接";
        setConnectionState(Connected);
        emit connected();
        break;

    case QModbusDevice::ClosingState:
        qInfo() << "Modbus 状态: 断开中...";
        break;
    }
}

// 处理错误
void ModbusService::onErrorOccurred(QModbusDevice::Error error)
{
    if (error == QModbusDevice::NoError)
        return;

    QString errorString = m_modbusClient->errorString();
    qWarning() << "Modbus 错误:" << errorString;

    setError(errorString);
    setConnectionState(Error);
    emit connectionError(errorString);
}

// 处理读取完成
void ModbusService::onReadReady()
{
    QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
    if (!reply)
        return;

    // 确保 reply 会被删除
    reply->deleteLater();

    if (reply->error() == QModbusDevice::NoError)
    {
        // 读取成功
        const QModbusDataUnit unit = reply->result();
        QVector<quint16> values;

        for (int i = 0; i < unit.valueCount(); ++i)
        {
            values.append(unit.value(i));
        }

        qDebug() << "读取成功: 地址" << unit.startAddress()
                 << "数量" << unit.valueCount()
                 << "数据:" << values;

        emit registersRead(unit.startAddress(), values);
    }
    else
    {
        // 读取失败
        QString error = QString("读取失败: %1").arg(reply->errorString());
        qWarning() << error;
        setError(error);
        emit readError(error);
    }
}

// 设置连接状态
void ModbusService::setConnectionState(ConnectionState state)
{
    if (m_connectionState != state)
    {
        m_connectionState = state;
        emit connectionStateChanged(state);
    }
}

// 设置错误信息
void ModbusService::setError(const QString &error)
{
    m_lastError = error;
    qWarning() << "ModbusService 错误:" << error;
}
